<?php


namespace App\Imports;

use App\Exceptions\ApiException;
use App\Models\Classify;
use App\Models\PartCompany;
use App\Models\PartCompanyClassify;
use App\Models\Project;
use App\Models\ProjectClassify;
use App\Services\ProjectClassifyService;
use App\Services\ProjectService;
use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithColumnLimit;
use Maatwebsite\Excel\Concerns\WithLimit;
use Maatwebsite\Excel\Concerns\WithStartRow;

class ProjectClassifyImport implements ToModel, WithStartRow, WithColumnLimit, WithLimit, SkipsEmptyRows
{
    protected $partCompanyType;
    protected $limit;
    protected $startRow;
    protected $endColumn;
    protected $partCompanyId;
    protected $importCountKey;
    protected $projectClassifyList;
    protected $partCompany;
    protected $templateId;

    public function __construct($partCompanyId, $importCountKey)
    {
        $redisKey = ProjectClassifyService::getProjectClassifyKey($partCompanyId);
        if (!redis()->get($redisKey)) {
            throw new ApiException('请刷新页面~'); //目的是让用户请求下 【获取项目分类树】接口
        }
        $this->limit               = 1000; //只读取前1000行
        $this->startRow            = 2;    //从第几行开始
        $this->endColumn           = 'F';  //指定到那一列为止
        $this->partCompanyId       = $partCompanyId; //参建单位
        $this->projectClassifyList = json_decode(redis()->get($redisKey), true);
        $this->importCountKey      = $importCountKey; //只读取前1000行
        $this->partCompany         = PartCompany::query()->find($this->partCompanyId);
        $this->templateId          = Project::query()->where('id', $this->partCompany->project_id)->value('template_id');
    }

    public function model(array $row)
    {
        if ($row[0] && is_numeric($row[0])) {
            $title      = $row[4];
            $archivesNo = $row[5];
            $this->checkValid($row, $this->partCompanyId, $archivesNo); //初步检查验证
            $parentId = 0;
            foreach ($this->projectClassifyList as $val) {
                $archivesNoData1 = ProjectClassifyService::sliceArchivesNo($val['archives_no']);
                $archivesNoData2 = ProjectClassifyService::sliceArchivesNo($archivesNo);
                if (($archivesNoData1 == $archivesNoData2) && empty($val['part_company_id'])) { //底模板里面的没有指定参建单位
                    $parentId = $val['classify_id'];
                    break;
                }
            }
            $info = ProjectClassify::query()
                ->where('part_company_id', $this->partCompanyId)
                ->where('archives_no', format_archives_no($archivesNo))
                ->first();
            if (empty($info)) {
                $archivesNoData = ProjectClassifyService::sliceArchivesNo($archivesNo);

                $data                      = [];
                $data['title']             = format_str($title);
                $data['parent_id']         = $parentId;
                $data['template_id']       = 0; //这个应该为 0
                $data['archives_no']       = format_archives_no($archivesNo); //档案号
                $data['type']              = $archivesNoData['type']; //J或K
                $data['project_no']        = $archivesNoData['project_no']; //项目代码
                $data['stage_code']        = $archivesNoData['stage_code']; //阶段代码
                $data['major_code']        = $archivesNoData['major_code']; //专业代码
                $data['creator_id']        = user_id();
                $data['part_company_id']   = $this->partCompany->id;
                $data['part_company_type'] = $this->partCompany->type;
                $data['add_direct']        = 1; //0不可直接添加，1可以
                $data['is_can_edit']       = 1; //0不可以，1可以编辑
                $data['created_at']        = date('Y-m-d H:i:s'); //创建时间

                $classify            = Classify::query()->create($data);
                $data['classify_id'] = $classify->id;
                $classify->delete(); //创建之后，获取主键再删除
                $projectClassify = ProjectClassify::query()->create($data);

                PartCompanyClassify::query()->insert([
                    'project_id'          => $this->partCompany->project_id,
                    'part_company_id'     => $this->partCompany->id,
                    'project_classify_id' => $projectClassify->id,
                    'created_at'          => now(),
                ]);
                redis()->incr($this->importCountKey);
            }
        }
    }

    /**
     * 初步验证导入数据的合法性
     * 要求：格式正确，解析到的项目代码正确
     */
    public static function checkValid($row, $partCompanyId, $archivesNo)
    {
        if ($row[0] == '序号') {
            if (format_table_label($row[1]) != '合同段名称'
                || format_table_label($row[2]) != '合同段'
                || format_table_label($row[3]) != '专业名称'
                || format_table_label($row[4]) != '单位工程名称'
                || format_table_label($row[5]) != '档案案卷号') {
                throw new ApiException("格式错误！列属性名必须和模板完全一致，并核对数据列【A~F】");
            }
        }
        $partCompany    = PartCompany::query()->find($partCompanyId);
        $projectInfo    = ProjectService::getInfo($partCompany->project_id);
        $archivesNoData = ProjectClassifyService::sliceArchivesNo($archivesNo);
        if ($projectInfo->document_number != $archivesNoData['project_no']) {
            throw new ApiException("有【档案案卷号】项目代码是{$archivesNoData['project_no']}，必须是{$projectInfo->document_number}");
        }
    }

    /**
     * 直接过滤表头，第一块数据含表头
     *
     * @return int
     */
    public function startRow(): int
    {
        return $this->startRow;
    }

    /**
     * 指定到那一列为止，G代表读取到G列就不再读取
     *
     * @return string
     */
    public function endColumn(): string
    {
        return $this->endColumn;
    }

    /**
     * 限制读取到第几行
     *
     * @return int
     * @author: lxk
     * @date: 2023/9/13 14:14
     */
    public function limit(): int
    {
        return $this->limit;
    }
}
